package utils

import (
	"encoding/json"
	"fmt"
	"github.com/mitchellh/mapstructure"
	"reflect"
)

func Struct2Struct(source interface{}, target interface{}) error {
	skd := reflect.TypeOf(source).Kind()
	if skd != reflect.Ptr {
		return fmt.Errorf("type of param st must be ptr")
	}
	tkd := reflect.TypeOf(target).Kind()
	if tkd != reflect.Ptr {
		return fmt.Errorf("type of param st must be ptr")
	}
	sct := reflect.TypeOf(source).Elem()
	scv := reflect.ValueOf(source).Elem()
	tt := reflect.TypeOf(target).Elem()
	mp := make(map[string]interface{})
	for i := 0;i < tt.NumField(); i++ {
		mp[tt.Field(i).Name] = 1
	}
	var data= make(map[string]interface{})
	for i := 0; i < sct.NumField(); i++ {
		if _, ok := mp[sct.Field(i).Name]; ok {
			data[sct.Field(i).Name] = scv.Field(i).Interface()
		}
	}
	if err := mapstructure.Decode(data, target); err != nil {
		return err
	}
	return nil
}


func Struct2Json(st interface{}) (string, error) {
	jsonBt, err := json.Marshal(st)
	if err != nil {
		return "", fmt.Errorf("Struct To Json ERROR: %v \n",err)
	}
	return string(jsonBt), nil
}

//todo:主要利用struct2json，omitempty移除多余字段
func St2Js2Mp(st interface{}) (map[string]interface{},error) {
	jsonBt, err := json.Marshal(st)
	if err != nil {
		return nil, fmt.Errorf("St2Js2Mp Error => %v\n",err.Error())
	}
	m := make(map[string]interface{})
	err = json.Unmarshal(jsonBt, &m)
	if err != nil {
		return nil, fmt.Errorf("St2Js2Mp Error => %v\n",err.Error())
	}
	return m, nil
}

func Json2Struct(jsonstr string, st interface{}) (interface{}, error) {
	err := json.Unmarshal([]byte(jsonstr), st)
	if err != nil {
		return nil, err
	}
	return st, nil
}

